#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=202;
const int M=10005;

int n,m,s,t;
int flag[N][N];
struct edge{
    int to,next;
    LL w;
};
edge edges[M];
int head[N];
int cnt=1;
LL ans=0;

void adde(int u,int v,int w){
    edges[cnt].to=v;
    edges[cnt].w=w;
    edges[cnt].next=head[u];
    head[u]=cnt;
    cnt++;
}


int level[N];
int now[N];

bool bfs(){
    memset(level,0x3f,sizeof(level));
    queue<int> que;
    que.push(s);
    level[s]=0;
    now[s]=head[s];
    while(!que.empty()){
        int p=que.front();
        que.pop();
        for(int i=head[p];i!=0;i=edges[i].next){
            int t1=edges[i].to;
            LL w=edges[i].w;
            if(w==0) continue;
            if(level[t1]<=n) continue;
            now[t1]=head[t1];
            level[t1]=level[p]+1;
            que.push(t1);
            if(t==t1) return true;
        }
    }
    return false;
}

LL dfs(int x,LL addv)
{
    if(x==t) return addv;
    LL res=0;
    for(int i=now[x];i>0&&addv;i=edges[i].next){
        int t1=edges[i].to;
        LL w1=edges[i].w;
        now[x]=i;
        if(w1>0&&level[t1]==level[x]+1)
        {
            LL v1=dfs(t1,min(addv,w1));
            if(v1==0) level[t1]=INT_MAX;
            int pos=i,neg;
            if(pos%2==0) neg=pos-1;
            else neg=pos+1;
            edges[pos].w-=v1;
            edges[neg].w+=v1;
            res+=v1;
            addv-=v1;
        }
    }
    return res;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&s,&t);
    memset(flag,0,sizeof(flag));
    for(int i=0;i<m;i++){
        int s1,t1;
        LL w1;
        scanf("%d%d%lld",&s1,&t1,&w1);
        if(flag[s1][t1]==0){
            flag[s1][t1]=cnt;
            flag[t1][s1]=cnt+1;
            adde(s1,t1,w1);
            adde(t1,s1,0);
        }
        else{
            edges[flag[s1][t1]].w+=w1;
        }
    }
    const LL inf=LLONG_MAX;
    while(bfs()){
        ans+=dfs(s,inf);    
    }
    printf("%lld",ans);
    return 0;
}